package edu.mse.camel.client.uml.collab.handlers;

import java.io.ByteArrayInputStream;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;

import edu.mse.camel.client.core.events.model.BaselineResourceUpdate;
import edu.mse.camel.client.eventbus.pubsub.ISubscriber;
import edu.mse.camel.client.events.EventIDs;
import edu.mse.camel.client.events.IEvent;
import edu.mse.camel.client.events.peer.ReceiveGenericPeerEvent;

import edu.mse.camel.client.log.Debug;
import edu.mse.camel.client.uml.collab.CollabPlugin;

public class ResourceUpdateHandler implements ISubscriber {
	
	private IProject OpenOrCreatProject (String name) {
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		IWorkspaceRoot root = workspace.getRoot();
		IProject project = root.getProject(name);
		
		if( project.exists() ) {
			try {
				project.open(null);
			} catch (CoreException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				Debug.log_warning(CollabPlugin.PLUGIN_ID, "Opening existing project failed");
			}
		} 
		else {
			// project doesn't exist, create a new one
			IProjectDescription desc = workspace.newProjectDescription(project.getName());
			try {
				project.create(desc, null);
				project.open(null);
			} catch (CoreException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				project = null;
				Debug.log_warning(CollabPlugin.PLUGIN_ID, "Project creation failed");
			}
		}
		return project;
	}
	
	private void HandleOnetimeResourceUpdate(BaselineResourceUpdate update) {
		IProject project = OpenOrCreatProject(update.getOriginalProjectName());
		IFile resourceFile = project.getFile(update.getOriginalFileName());
		
		ByteArrayInputStream stream = new ByteArrayInputStream(update.getFileBuffer());
		try {
			if(resourceFile.exists()) {
				// don't force overwrite (recommended by eclipse document)
				// keep history (no idea how to recover that)
				// no progress monitor (the file should not be very large)
				resourceFile.setContents(
						stream, false, true, new NullProgressMonitor());
			}
			else {
				// don't force overwrite (recommended by eclipse document)
				// no progress monitor (the file should not be very large)
				resourceFile.create(stream, false, new NullProgressMonitor());
			}
			
		} catch (CoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	
	@Override
	public void notifyEvent(IEvent event) {
		if(event instanceof ReceiveGenericPeerEvent) {
			ReceiveGenericPeerEvent generic = (ReceiveGenericPeerEvent) event;
			if ( generic.getEventID().equalsIgnoreCase(EventIDs.BASELINE_RESOURCE_UPDATE_EVENT)) {
				HandleOnetimeResourceUpdate(generic.readObject(BaselineResourceUpdate.class));
			}
			else {
				Debug.log_warning(CollabPlugin.PLUGIN_ID, "WARNING: Unknown generic event type for ResourceUpdateHandler");
			}
		}
		else {
			Debug.log_warning(CollabPlugin.PLUGIN_ID, "WARNING: Unknown event type for ResourceUpdateHandler");
		}
	}

}
